package com.kun.springbootdelivery.controller;


import cn.hutool.json.JSONUtil;
import com.kun.springbootdelivery.entity.Delivery;
import com.kun.springbootdelivery.entity.Order;
import com.kun.springbootdelivery.service.impl.DeliveryServiceImpl;
import com.rabbitmq.client.Channel;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.amqp.rabbit.connection.CorrelationData;
import org.springframework.amqp.support.AmqpHeaders;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.messaging.handler.annotation.Header;
import org.springframework.web.bind.annotation.*;

import org.springframework.web.client.RestTemplate;

import java.io.IOException;

/**
 * <p>
 *  前端控制器
 * </p>
 *
 * @author kunkun
 * @since 2025-02-25
 */
@RestController
@RequestMapping("/delivery")
public class DeliveryController {

    @Autowired
    private DeliveryServiceImpl deliveryService;



    @GetMapping("/insert")
    public String string(@RequestParam("orderId")Integer orderId,
                            @RequestParam("userId")Integer userId,
                            @RequestParam("orderContent")String orderContent) throws InterruptedException {
        Delivery delivery = new Delivery();
        delivery.setOrderId(orderId);
        delivery.setUserId(userId);
        delivery.setOrderContent(orderContent);
        deliveryService.insertDelivery(delivery);
        //模拟延迟
        Thread.sleep(3000);
        return "success";
    }

    @RabbitListener(queues = "order_queue_1")
    public void receiveMessage(String orderMessage, Channel channel, CorrelationData correlationData,
                               @Header(AmqpHeaders.DELIVERY_TAG) long tag) throws IOException {
        //1. 接收到消息，开始处理消息
        try{
            System.out.println("接收到消息，开始处理消息: " + orderMessage);
            Order order = JSONUtil.toBean(orderMessage, Order.class);
            Delivery delivery = new Delivery();
            delivery.setOrderId(order.getOrderId());
            delivery.setUserId(order.getUserId());
            delivery.setOrderContent(order.getOrderContent());
            System.out.println(1/0);    //手动模拟异常
            deliveryService.insertDelivery(delivery);
            channel.basicAck(tag, false);    //消息确认
        }catch (Exception e){
            //2. 处理失败，将消息重新放回队列
            //tag: 标识消息的唯一性
            //multiple: 是否批量确认，false：只会否定当前这一条，true：会否定所有之前消息（即tag小于当前tag的消息）
            //requeue: 是否重新放回队列（可能会造成死循环）
            channel.basicNack(tag, false, false);
        }
    }

    @RabbitListener(queues = "dead-letter-queue-1")
    public void receiveMessageByDeadLetter(String orderMessage, Channel channel, CorrelationData correlationData,
                               @Header(AmqpHeaders.DELIVERY_TAG) long tag) throws IOException {
        //1. 接收到消息，开始处理消息
        try{
            System.out.println("开始处理死信队列的消息: " + orderMessage);
            Order order = JSONUtil.toBean(orderMessage, Order.class);
            Delivery delivery = new Delivery();
            delivery.setOrderId(order.getOrderId());
            delivery.setUserId(order.getUserId());
            delivery.setOrderContent(order.getOrderContent());
            deliveryService.insertDelivery(delivery);
            channel.basicAck(tag, false);    //消息确认
        }catch (Exception e){
            System.out.println("死信队列消息处理失败，请人工处理！");
            channel.basicNack(tag, false, false);
        }
    }

}

